package com.opages.netty.demo.chat;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;

/**
 * @author daizhong.liu
 * @create 2021-12-02 14:58
 **/
public class NIOService {
    public static void main(String[] args) throws IOException {
        //创建服务端
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        //绑定本地IP与端口
        serverSocketChannel.socket().bind(new InetSocketAddress("127.0.0.1",8889));
        //选择非阻塞
        serverSocketChannel.configureBlocking(false);
        //打开一个选择器
        Selector selector = Selector.open();
        //注册accept事件到selector
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        while (true) {
            //检测事件，不仅仅是连接事件，下面还有读事件
            if(selector.select(1000) == 0) {
                continue;
            }
            //存在事件请求
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            Iterator<SelectionKey> keyIterator = selectionKeys.iterator();
            //遍历事件请求
            while (keyIterator.hasNext()) {
                SelectionKey selectionKey = keyIterator.next();
                //连接请求
                if(selectionKey.isAcceptable()) {
                    //打开客户端连接
                    SocketChannel socketChannel = serverSocketChannel.accept();
                    //设置为非阻塞
                    socketChannel.configureBlocking(false);
                    //注册客户端为读事件到selector
                    socketChannel.register(selector,SelectionKey.OP_READ, ByteBuffer.allocate(1024));
                }
                //读请求
                if(selectionKey.isReadable()) {
                    //获取通道
                    SocketChannel channel = (SocketChannel)selectionKey.channel();
                    //获取通道中的缓存
                    ByteBuffer buffer = (ByteBuffer)selectionKey.attachment();
                    //将数据读入缓存
                    channel.read(buffer);
                    System.err.println("客户端："+new String(buffer.array()));
                }
                //手动从集合中移动当前的selectionKey, 防止重复操作
                keyIterator.remove();
            }
        }
    }
}
